package com.cykj.pos.util;

import com.alibaba.fastjson.JSONObject;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Map;

/**
 * @project: zbh-api
 * @package: vip.zhongbaohui.api.product.saas.core.util
 * @class: AESUtil
 * @description: AES加密工具类
 */
@Component
public class AESUtil {
    private static Logger logger = LoggerFactory.getLogger(AESUtil.class);

    public final static String ALGO_AES_CBC_NoPadding = "AES/CBC/NoPadding";
    public final static String ALGO_AES_CBC_PKCS5Padding = "AES/CBC/PKCS5Padding";
    public final static String ALGO_AES_ECB_NoPadding = "AES/ECB/NoPadding";
    public final static String ALGO_AES_ECB_PKCS5Padding = "AES/ECB/PKCS5Padding";

    private static String appkey;

    private static String appsecret;

//    @Value("${sys-set.xlw.app_key}")
//    private String saasAppkey;
//
//    @Value("${sys-set.xlw.app_secret}")
//    private String saasAppsecret;
    public AESUtil(){

    }
    public AESUtil(String saasAppkey, String saasAppsecret){
        appkey = saasAppkey;
        appsecret = saasAppsecret;
    }
//    @PostConstruct
//    public void get() {
//        appkey = this.saasAppkey;
//        appsecret = this.saasAppsecret;
//    }

    public static String getAppkey() {
        return appkey;
    }

    public static String getAppsecret() {
        return appsecret;
    }


    /**
     *
     * @param algorithm
     * @param cryptoMode
     * @param key
     * @param iv Optional. It should be null when ECB mode.
     * @return
     * @throws InvalidKeyException
     * @throws NoSuchAlgorithmException
     * @throws NoSuchPaddingException
     * @throws InvalidAlgorithmParameterException
     */
    public static Cipher createCipher(
            String algorithm, int cryptoMode,
            byte[] key, byte[] iv
            ) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException {
        Cipher cipher = Cipher.getInstance(algorithm);
        if(iv != null) {
            cipher.init(
                    cryptoMode,
                    new SecretKeySpec(key, "AES"),
                    new IvParameterSpec(iv)
                    );
        } else {
            cipher.init(cryptoMode, new SecretKeySpec(key, "AES"));
        }
        return cipher;
    }

    /**
     * AES加密
     *
     * @return byte
     */
    public static byte[] encrypt(
            String algorithm,
            byte[] key, byte[] iv,
            byte[] bytes
            ) throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException {
        return createCipher(algorithm, Cipher.ENCRYPT_MODE, key, iv).doFinal(bytes);
    }

    /**
     * AES解密
     *
     * @return byte
     */
    public static byte[] decrypt(
            String algorithm,
            byte[] key, byte[] iv,
            byte[] bytes
            ) throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException {
        return createCipher(algorithm, Cipher.DECRYPT_MODE, key, iv).doFinal(bytes);
    }

    /**
     * AES加密
     *
     * @return byte
     */
    public static String encrypt(Map<String,Object> data, String saasAppsecret) throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException {
        JSONObject jsonObject=new JSONObject();
        for (String key :data.keySet()) {
            jsonObject.put(key,data.get(key));
        }
        String key = saasAppsecret;
        String ivString = key;
        //偏移量
        byte[] iv = ivString.getBytes();
        Cipher cipher = Cipher.getInstance(ALGO_AES_CBC_NoPadding);
        int blockSize = cipher.getBlockSize();
        byte[] dataBytes = jsonObject.toString().getBytes();
        int length = dataBytes.length;
        //计算需要填充长度
        if(length % blockSize != 0){
            length = length + (blockSize - (length % blockSize));
        }
        byte[] plaintext = new byte[length];
        //填充补位数据
        System.arraycopy(dataBytes,0,plaintext,0,dataBytes.length);
        SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(),"AES");
        //设置偏移量参数
        IvParameterSpec ivSpec = new IvParameterSpec(iv);
        cipher.init(Cipher.ENCRYPT_MODE,keySpec,ivSpec);
        byte[] encryped = cipher.doFinal(plaintext);
        String encrypedStrr = Base64.encode(encryped);
        return encrypedStrr;
    }

    public static JSONObject decrypt(String requestBody,String saasAppsecret) throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException {
        String key = saasAppsecret;
        String ivString = key;
        //偏移量
        byte[] iv = ivString.getBytes();

        SecretKeySpec skey = new SecretKeySpec(key.getBytes(), "AES");
        IvParameterSpec ivSpec = new IvParameterSpec(ivString.getBytes(), 0, iv.length);
        Cipher cipher = Cipher.getInstance(ALGO_AES_CBC_NoPadding);
        cipher.init(Cipher.DECRYPT_MODE, skey, ivSpec);// 初始化
        byte[] result = cipher.doFinal(new Base64().decode(requestBody));
        System.out.println(new String(result));
        JSONObject jsonObject=JSONObject.parseObject(new String(result));
        System.out.println(jsonObject.toJSONString());
        return jsonObject;
    }

    /**
     * AES解密
     *
     * @return byte
     */
    public static String decrypt1(String requestBody,String saasAppsecret) throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException {
        String key =saasAppsecret;
        String ivString = key;
        //偏移量
        byte[] iv = ivString.getBytes();
        byte[] encrypted = Base64.decode(requestBody);
        Cipher cipher = Cipher.getInstance(ALGO_AES_CBC_NoPadding);
        SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(),"AES");
        //设置偏移量参数
        IvParameterSpec ivSpec = new IvParameterSpec(iv);
        cipher.init(Cipher.DECRYPT_MODE,keySpec,ivSpec);
        byte[] original = cipher.doFinal(encrypted);
        String originalStr = new String(original);
        return originalStr;
    }
}
